package org.example.video.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.commonapi.domain.R;
import org.example.commonapi.domain.User;
import org.example.commonapi.domain.VideoHistory;
import org.example.commonapi.mapper.UserMapper;
import org.example.commonapi.mapper.VideoHistoryMapper;
import org.example.commonapi.util.JwtUtil;
import org.example.commonapi.domain.CollectVideo;
import org.example.commonapi.domain.Personality;
import org.example.commonapi.domain.Video;
import org.example.commonapi.mapper.CollectVideoMapper;
import org.example.commonapi.mapper.PersonalityMapper;
import org.example.commonapi.mapper.VideoMapper;
import org.example.commonapi.vo.VideoHistoryVO;
import org.example.video.service.VideoService;
import org.example.commonapi.vo.VideoVO;
import org.example.video.strategy.VideoSortType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {

    @Autowired
    private VideoMapper videoMapper;

    @Autowired
    private PersonalityMapper personalityMapper;

    @Autowired
    private CollectVideoMapper collectVideoMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private VideoHistoryMapper videoHistoryMapper;

    @Resource
    private JwtUtil jwtUtil;



    @Override
    public R<List<VideoVO>> getHotVideoList() {
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        // 根据当前播放量排序获取最热门视频
        queryWrapper.orderByDesc(Video::getPlayCount);
        List<Video> videoList = videoMapper.selectList(queryWrapper);
        List<VideoVO> videoVOList = new ArrayList<>();
        for (Video video : videoList) {
            LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
            userQueryWrapper.eq(User::getId, video.getTeacherId());
            User user = userMapper.selectOne(userQueryWrapper);
            VideoVO videoVO = new VideoVO();
            BeanUtils.copyProperties(video, videoVO);
            videoVO.setPublisherName(user.getUsername());
            videoVOList.add(videoVO);
        }
        return R.success(videoVOList);
    }

    @Override
    public R<List<VideoVO>> getTargetSubjectVideoList(String subject, VideoSortType sortType) {
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Video::getTag, subject);
        // 应用排序策略
        sortType.applySort(queryWrapper);

        List<Video> videoList = videoMapper.selectList(queryWrapper);
        List<VideoVO> videoVOList = new ArrayList<>();

        for (Video video : videoList) {
            User user = userMapper.selectOne(
                    new LambdaQueryWrapper<User>()
                            .eq(User::getId, video.getTeacherId())
            );

            VideoVO videoVO = new VideoVO();
            BeanUtils.copyProperties(video, videoVO);
            videoVO.setPublisherName(user.getUsername());
            videoVOList.add(videoVO);
        }

        return R.success(videoVOList);
    }

    // 保留原方法的重载（兼容旧调用）
    @Override
    public R<List<VideoVO>> getTargetSubjectVideoList(String subject) {
        return getTargetSubjectVideoList(subject, VideoSortType.defaultSort());
    }

    @Override
    public R<List<VideoHistoryVO>> getVideoHistory(HttpServletRequest request) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        LambdaQueryWrapper<VideoHistory> queryWrapper = new LambdaQueryWrapper<>();
        // 查询一个月内的观看记录
        queryWrapper.ge(VideoHistory::getWatchTime, LocalDateTime.now().minusMonths(1));
        queryWrapper.eq(VideoHistory::getUserId, userId);
        List<VideoHistory> videoHistoryList = videoHistoryMapper.selectList(queryWrapper);
        List<VideoHistoryVO> videoHistoryVOList = new ArrayList<>();
        // 构造videoHistoryVO
        for (VideoHistory videoHistory : videoHistoryList) {
            VideoHistoryVO videoHistoryVO = new VideoHistoryVO();
            BeanUtils.copyProperties(videoHistory, videoHistoryVO);
            // 获取视频信息
            LambdaQueryWrapper<Video> videoQueryWrapper = new LambdaQueryWrapper<>();
            videoQueryWrapper.eq(Video::getId, videoHistory.getVideoId());
            Video video = videoMapper.selectOne(videoQueryWrapper);
            // 获取视频标签
            String tags = video.getTag();
            // 视频标签使用逗号分割
            String[] tagList = tags.split(",");
            LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
            userQueryWrapper.eq(User::getId, video.getTeacherId());
            User user = userMapper.selectOne(userQueryWrapper);
            BeanUtils.copyProperties(video, videoHistoryVO);
            videoHistoryVO.setPublisherName(user.getUsername());
            videoHistoryVO.setTags(tagList);
            videoHistoryVO.setWatchTime(videoHistory.getWatchTime());
            videoHistoryVOList.add(videoHistoryVO);
        }
        return R.success(videoHistoryVOList);
    }

    @Override
    public R<List<List<Integer>>> getRecentDayVideoDetail(HttpServletRequest request) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        // 获取所有上传的视频
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Video::getTeacherId, userId);
        List<Video> videoList = videoMapper.selectList(queryWrapper);
        List<List<Integer>> videoDetailList = new ArrayList<>();
        List<Integer> videoPlayCountDetail = new ArrayList<>();
        List<Integer> videoCollectDetail = new ArrayList<>();
        if ( videoList.isEmpty()) {
            for ( int i = 0 ; i < 7 ; i ++ ) {
                videoPlayCountDetail.add(0);
                videoCollectDetail.add(0);
            }
        }else {
            // 获取近7天每天有多少人观看
            for (int i = 6; i >= 0; i--) {
                LambdaQueryWrapper<VideoHistory> videoHistoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
                videoHistoryLambdaQueryWrapper.ge(VideoHistory::getWatchTime, LocalDateTime.now().minusDays(i + 1));
                videoHistoryLambdaQueryWrapper.le(VideoHistory::getWatchTime, LocalDateTime.now().minusDays(i));
                videoHistoryLambdaQueryWrapper.in(VideoHistory::getVideoId, videoList.stream().map(Video::getId).collect(Collectors.toList()));
                Integer count = Math.toIntExact(videoHistoryMapper.selectCount(videoHistoryLambdaQueryWrapper));
                System.out.println("视频播放量：" + count);
                videoPlayCountDetail.add(count);
                LambdaQueryWrapper<CollectVideo> collectVideoLambdaQueryWrapper = new LambdaQueryWrapper<>();
                collectVideoLambdaQueryWrapper.ge(CollectVideo::getCollectTime, LocalDateTime.now().minusDays(i + 1));
                collectVideoLambdaQueryWrapper.le(CollectVideo::getCollectTime, LocalDateTime.now().minusDays(i));
                collectVideoLambdaQueryWrapper.in(CollectVideo::getVideoId, videoList.stream().map(Video::getId).collect(Collectors.toList()));
                Integer collectCount = Math.toIntExact(collectVideoMapper.selectCount(collectVideoLambdaQueryWrapper));
                videoCollectDetail.add(collectCount);
            }
        }
        videoDetailList.add(videoPlayCountDetail);
        videoDetailList.add(videoCollectDetail);
        return R.success(videoDetailList);
    }

    @Override
    public R<Boolean> getVideoCollectState(HttpServletRequest request, Integer videoId) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        LambdaQueryWrapper<CollectVideo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CollectVideo::getUserId, userId);
        queryWrapper.eq(CollectVideo::getVideoId, videoId);
        CollectVideo collectVideo = collectVideoMapper.selectOne(queryWrapper);
        if ( collectVideo == null ) {
            return R.success(false);
        }else {
            return R.success(true);
        }
    }



    @Override
    public R<Video> clickVideo(HttpServletRequest request, Integer videoId) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        // 1. 获取对应视频 让对应视频点击量增加
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Video::getId, videoId);
        Video video = videoMapper.selectOne(queryWrapper);
        video.setPlayCount(video.getPlayCount()+1);
        videoMapper.updateById(video);
        // 2.获取对应视频标签 插入新视频标签/更新标签点击次数
        String tags = video.getTag();
        // 视频标签使用逗号分割
        String[] tagList = tags.split(",");
        for (String tag : tagList) {
            LambdaQueryWrapper<Personality> personalityQueryWrapper = new LambdaQueryWrapper<>();
            personalityQueryWrapper.eq(Personality::getUserId, userId);
            personalityQueryWrapper.eq(Personality::getTag, tag);
            Personality personality = personalityMapper.selectOne(personalityQueryWrapper);
            if ( personality == null ) {
                // 之前不存在这个标签 创建一条数据
                personalityMapper.insert(new Personality(userId, tag,1));
            }else {
                // 之前存在这个标签 更新数据
                personalityMapper.update(new Personality(userId, tag, personality.getClickCount()+1), personalityQueryWrapper);
            }
        }
        // 3.添加观看记录
        LambdaQueryWrapper<VideoHistory> videoHistoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        videoHistoryLambdaQueryWrapper.eq(VideoHistory::getUserId, userId);
        videoHistoryLambdaQueryWrapper.eq(VideoHistory::getVideoId, videoId);
        VideoHistory videoHistory = videoHistoryMapper.selectOne(videoHistoryLambdaQueryWrapper);
        if ( videoHistory == null ) {
            // 不存在 插入一条
            videoHistoryMapper.insert(new VideoHistory(userId, videoId));
        }else {
            // 更新时间
            videoHistoryMapper.update(new VideoHistory(userId, videoId, Timestamp.valueOf(LocalDateTime.now())), videoHistoryLambdaQueryWrapper);
        }
        return R.success(video);
    }

    @Override
    public R addVideo(HttpServletRequest request,Video video) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        video.setTeacherId(userId);
        videoMapper.insert(video);
        return R.success();
    }

    @Override
    public R collectVideo(HttpServletRequest request, Integer videoId) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        LambdaQueryWrapper<CollectVideo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CollectVideo::getUserId, userId);
        queryWrapper.eq(CollectVideo::getVideoId, videoId);
        CollectVideo existedCollectVideo = collectVideoMapper.selectOne(queryWrapper);
        if ( existedCollectVideo != null ) {
            // 存在已收藏的数据 转化为取消收藏
            collectVideoMapper.delete(queryWrapper);
            return R.success();
        }
        CollectVideo collectVideo = new CollectVideo(userId, videoId,LocalDateTime.now());
        collectVideoMapper.insert(collectVideo);
        return R.success();
    }

    @Override
    public R<List<VideoVO>> getMyCollectVideo(HttpServletRequest request) {
        Long userId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        LambdaQueryWrapper<CollectVideo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CollectVideo::getUserId, userId);
        List<CollectVideo> collectVideoList = collectVideoMapper.selectList(queryWrapper);
        List<VideoVO> videoVOList = new ArrayList<>();
        for (CollectVideo collectVideo : collectVideoList) {
            LambdaQueryWrapper<Video> videoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            videoLambdaQueryWrapper.eq(Video::getId, collectVideo.getVideoId());
            Video video = videoMapper.selectOne(videoLambdaQueryWrapper);
            Long teacherId = video.getTeacherId();
            // 查询出发布者信息
            LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userLambdaQueryWrapper.eq(User::getId, teacherId);
            User user = userMapper.selectOne(userLambdaQueryWrapper);
            VideoVO videoVO = VideoVO.builder()
                    .id(video.getId())
                    .title(video.getTitle())
                    .cover(video.getCover())
                    .publisherName(user.getUsername())
                    .playCount(video.getPlayCount())
                    .collectCount(video.getCollectCount())
                    .createTime(Timestamp.valueOf(collectVideo.getCollectTime()))
                    .build();
            videoVOList.add(videoVO);
        }
        return R.success(videoVOList);
    }

    @Override
    public R<List<Video>> getMyVideo(HttpServletRequest request) {
        Long teacherId = jwtUtil.parseJwt(request.getHeader("token")).getId();
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Video::getTeacherId, teacherId);
        List<Video> videoList = videoMapper.selectList(queryWrapper);
        return R.success(videoList);
    }

    @Override
    public R<List<Video>> searchVideoByTitle(String title) {
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Video::getTitle, title);
        List<Video> videoList = videoMapper.selectList(queryWrapper);
        return R.success(videoList);
    }

    @Override
    public R<Video> getVideoInfoById(Integer videoId) {
        LambdaQueryWrapper<Video> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Video::getId, videoId);
        Video video = videoMapper.selectOne(queryWrapper);
        if ( video == null ) {
            return R.error("视频不存在！");
        }
        return R.success(video);
    }


}
